const schedule = require('node-schedule');
const { sendMail } = require('../config/email');
const ScheduledEmail = require('../models/ScheduledEmail');
const { Op } = require('sequelize');

class EmailScheduler {
    constructor() {
        this.jobs = new Map();
        this.initialized = false;
    }

    async initialize() {
        if (this.initialized) return;
        
        try {
            // 加载所有待发送的定时邮件
            const pendingEmails = await ScheduledEmail.findAll({
                where: {
                    status: 'pending',
                    scheduleTime: {
                        [Op.gt]: new Date() // 只加载未来的邮件
                    },
                    attempts: {
                        [Op.lt]: 3
                    }
                }
            });

            console.log(`加载了 ${pendingEmails.length} 个待发送的定时邮件`);

            // 为每个待发送的邮件创建定时任务
            pendingEmails.forEach(email => {
                this.scheduleEmail(email);
            });

            // 每分钟检查一次失败的邮件
            schedule.scheduleJob('*/1 * * * *', () => this.checkFailedEmails());

            this.initialized = true;
        } catch (error) {
            console.error('初始化邮件调度器失败:', error);
        }
    }

    scheduleEmail(email) {
        try {
            // 如果时间已过，立即发送
            if (new Date(email.scheduleTime) <= new Date()) {
                this.sendEmail(email);
                return;
            }

            // 创建定时任务
            const job = schedule.scheduleJob(email.scheduleTime, async () => {
                await this.sendEmail(email);
            });

            // 保存任务引用
            this.jobs.set(email.id, job);
            
            console.log(`已安排邮件 ID:${email.id} 在 ${email.scheduleTime} 发送`);
        } catch (error) {
            console.error(`安排邮件发送失败 ID:${email.id}:`, error);
        }
    }

    async sendEmail(email) {
        try {
            await sendMail({
                to: email.to,
                subject: '你收到了一封定时邮件',
                message: email.content
            });

            await email.update({
                status: 'sent'
            });

            // 移除已完成的任务
            this.jobs.delete(email.id);
            
            console.log(`邮件 ID:${email.id} 发送成功`);
        } catch (error) {
            console.error(`发送邮件失败 ID:${email.id}:`, error);
            await email.update({
                attempts: email.attempts + 1,
                status: email.attempts >= 2 ? 'failed' : 'pending'
            });
        }
    }

    async checkFailedEmails() {
        try {
            const failedEmails = await ScheduledEmail.findAll({
                where: {
                    status: 'pending',
                    scheduleTime: {
                        [Op.lte]: new Date()
                    },
                    attempts: {
                        [Op.lt]: 3
                    }
                }
            });

            for (const email of failedEmails) {
                if (!this.jobs.has(email.id)) {
                    this.scheduleEmail(email);
                }
            }
        } catch (error) {
            console.error('检查失败邮件时出错:', error);
        }
    }

    async addEmail(emailData) {
        try {
            const email = await ScheduledEmail.create(emailData);
            this.scheduleEmail(email);
            return email;
        } catch (error) {
            console.error('添加定时邮件失败:', error);
            throw error;
        }
    }

    cancelEmail(emailId) {
        const job = this.jobs.get(emailId);
        if (job) {
            job.cancel();
            this.jobs.delete(emailId);
            return true;
        }
        return false;
    }
}

// 创建单例实例
const emailScheduler = new EmailScheduler();

module.exports = emailScheduler; 